package api

import (
	"html"

	"github.com/gin-gonic/gin"
	"zhonghui/console/service"
	"zhonghui/console/structs"
	"zhonghui/console/warehouse/cfgx"
	"zhonghui/console/warehouse/dbx/db_zh_kernel"
	"zhonghui/console/warehouse/envx"
	"zhonghui/console/warehouse/helperx"
	"zhonghui/console/warehouse/modelx/model_zh_kernel"
	"zhonghui/console/warehouse/respx"
)

func (server *Server) GetUser(c *gin.Context) {
	user := service.GetUserFromToken(c.GetHeader("Authorization"))
	if user == nil {
		respx.UnAuth(c)
		return
	}

	openId := ""
	if user.OpenID != nil {
		openId = *user.OpenID
	}

	// 非生产环境忽略open_id
	if !envx.InProd() && openId == "" {
		openId = "test_open_id"
	}

	resp := structs.GetUserResp{
		Id:        user.ID,
		Nickname:  user.Nickname,
		RealName:  user.RealName,
		Phone:     user.Phone[:3] + "****" + user.Phone[7:],
		Position:  user.Position,
		OpenId:    openId,
		IsAdmin:   service.IsAdmin(user.ID),
		CreatedAt: user.CreatedAt.Format(helperx.TimeLayoutCommon),
	}

	respx.Success(c, resp, nil)
}

func (server *Server) GetUsers(c *gin.Context) {
	user := service.GetUserFromToken(c.GetHeader("Authorization"))
	if user == nil {
		respx.UnAuth(c)
		return
	}

	if !service.CanDo(user.ID, "*:*") {
		respx.Alert(c, "没有权限")
		return
	}

	// 查询管理员列表
	managers := make([]model_zh_kernel.ConsoleManager, 0)
	if err := db_zh_kernel.Client().Preload("Groups").Order("id desc").Find(&managers).Error; err != nil {
		respx.Alert(c, "获取管理员列表错误")
		return
	}

	resp := make([]structs.GetUsersResp, 0)
	for _, manager := range managers {
		// 遍历所属的用户组列表
		groups := make([]string, 0)
		for _, group := range manager.Groups {
			groups = append(groups, group.Name)
		}

		temp := structs.GetUsersResp{
			Id:        manager.ID,
			Phone:     manager.Phone,
			RealName:  manager.RealName,
			Position:  manager.Position,
			Nickname:  manager.Nickname,
			IsActive:  manager.IsActive == 1,
			Groups:    groups,
			CreatedAt: manager.CreatedAt.Format(helperx.TimeLayoutCommon),
		}

		resp = append(resp, temp)

	}

	respx.Success(c, resp, nil)
}

func (server *Server) PostUsers(c *gin.Context) {
	req := structs.PostUsersReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		respx.Bad(c, err)
		return
	}

	user := service.GetUserFromToken(c.GetHeader("Authorization"))
	if user == nil {
		respx.UnAuth(c)
		return
	}

	if !service.CanDo(user.ID, "*:*") {
		respx.Alert(c, "没有权限")
		return
	}

	// 检查手机
	if !helperx.IsPhone(req.Phone) {
		respx.Alert(c, "手机号格式不合法")
		return
	}

	// 检查重复
	manager := model_zh_kernel.ConsoleManager{}
	if err := db_zh_kernel.ClientCtx(c).Where("phone = ?", req.Phone).Take(&manager).Error; err == nil {
		respx.Alert(c, "已存在该手机号的管理员")
		return
	}

	// 处理密码
	password := helperx.RandomString(16)
	if envx.InDev() || envx.InTest() {
		password = "123456"
	}
	key := cfgx.Cfg().GetString("console.app_key")
	secret, err := helperx.AesEncrypt(password, key[:16], key[16:], false)
	if err != nil {
		respx.Alert(c, "创建用户密钥失败")
		return
	}

	// 处理otp
	otpUrl, otpSecret, err := service.MakeOtp(req.Phone)
	if err != nil {
		respx.Alert(c, "创建用户两部验证失败")
		return
	}

	// 新建
	newManager := model_zh_kernel.ConsoleManager{
		Phone:     req.Phone,
		Password:  secret,
		RealName:  html.EscapeString(req.RealName),
		Position:  html.EscapeString(req.Position),
		OtpSecret: otpSecret,
		IsActive:  1,
	}
	if err := db_zh_kernel.ClientCtx(c).Save(&newManager).Error; err != nil {
		respx.Alert(c, "创建用户失败")
		return
	}

	// todo 全都是管理员
	db_zh_kernel.ClientCtx(c).Exec("insert ignore into console_group_manager (group_id, manager_id) values (?, ?)", 1, newManager.ID)

	resp := structs.PostUsersResp{
		Phone:    req.Phone,
		Password: password,
		OtpUrl:   otpUrl,
	}

	respx.Success(c, resp, nil)
}

func (server *Server) PutUsers(c *gin.Context) {
	req := structs.PutUsersReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		respx.Bad(c, err)
		return
	}

	user := service.GetUserFromToken(c.GetHeader("Authorization"))
	if user == nil {
		respx.UnAuth(c)
		return
	}

	if !service.CanDo(user.ID, "*:*") {
		respx.Alert(c, "没有权限")
		return
	}

	// 查询管理员
	manager := model_zh_kernel.ConsoleManager{}
	if err := db_zh_kernel.ClientCtx(c).Where("id = ?", c.Param("id")).Take(&manager).Error; err != nil {
		respx.Alert(c, "无法查到该用户")
		return
	}

	if manager.ID == 1 {
		respx.Alert(c, "超级管理员不允许修改")
		return
	}

	// 修改信息
	manager.RealName = html.EscapeString(req.RealName)
	manager.Position = html.EscapeString(req.Position)
	if req.IsActive {
		manager.IsActive = 1
	} else {
		manager.IsActive = 0
	}

	if err := db_zh_kernel.ClientCtx(c).Save(&manager).Error; err != nil {
		respx.Alert(c, "修改用户失败")
		return
	}

	respx.Success(c, nil, nil)
}
